package station;

import java.io.FileWriter;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.ByteBuffer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;

public class DataSink implements Runnable {

	private DatagramSocket socket;
	private DatagramPacket packet;
	private long frame;
	private int i;
	private byte[] buffer;
	private boolean running;
	
	private static final int BUFFERSIZE = 33 + 8;
	private static final int SLOTTIME = 50;
	
	private FileWriter file;
	
	public DataSink(int port) {
		// Initialize UDP-Communication
		try {
			this.buffer = new byte[BUFFERSIZE];
			this.packet = new DatagramPacket(this.buffer, BUFFERSIZE);
			this.socket = new DatagramSocket(port);
			
			Calendar cal = Calendar.getInstance();
			
			file = new FileWriter(cal.get(Calendar.YEAR) + "_"
								+ (cal.get(Calendar.MONTH) + 1) + "_"
								+ cal.get(Calendar.DATE) + "_"
								+ cal.get(Calendar.HOUR) + "_"
								+ cal.get(Calendar.MINUTE) + "_"
								+ cal.get(Calendar.SECOND) + "_" 
								+ port + ".log", true);
		} catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} 
		
		// Thread
		this.running = true;
		Thread thread = new Thread(this);
		thread.start();
	}
	
	public void showMessage(byte... message) {
		byte[] tmpMsg = new byte[24];
		ByteBuffer buf = ByteBuffer.wrap(message);
		buf.get(tmpMsg, 0, tmpMsg.length);
		byte tmpSlot = buf.get(24);
		long tmpTime = buf.getLong(25);
		long tmpActTime = buf.getLong(33);
		short slot = this.getSlot(tmpActTime);
		
		long tmpFrame = tmpActTime / 1000; 
		if (this.frame != tmpFrame) {
			this.i = 0;
			this.frame = tmpFrame;
			DateFormat formatter = new SimpleDateFormat("ss");
			Calendar cal = Calendar.getInstance();
			cal.setTimeInMillis(tmpActTime);
			String output = String.format("----------------------------------------" + formatter.format(cal.getTime()) + "----------------------------------------" + System.getProperty("line.separator"));
			writeToFile(output);
		}
		
		String output = String.format("[%02d] %s (%d, next Slot: %02d) at %d in Slot %02d" + System.getProperty("line.separator"), ++this.i, new String(tmpMsg), tmpTime, tmpSlot, tmpActTime, slot);
//		System.out.printf(output);
		writeToFile(output);
	}
	
	@Override
	public void run() {
		while (this.running) {
			try {
				this.socket.receive(this.packet);
				this.showMessage(this.packet.getData());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	private short getSlot(long timestamp) {
		return (short) ((timestamp % 1000) / SLOTTIME);
	}
	
	private void writeToFile(String output) {
		try {
			file.append(output);
			file.flush();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
